home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / upc12bs1.zip / UUCICO / dcpfpkt.c < prev    next >
C/C++ Source or Header  |  1993-10-02  |  19KB  |  539 lines

  1. /*--------------------------------------------------------------------*/
  2. /*       d c p f p k t . c                                            */
  3. /*                                                                    */
  4. /*       UUCP 'f' protocol support                                    */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
  9. /*       Wonderworks.                                                 */
  10. /*                                                                    */
  11. /*       All rights reserved except those explicitly granted by       */
  12. /*       the UUPC/extended license agreement.                         */
  13. /*--------------------------------------------------------------------*/
  14.  
  15. /*--------------------------------------------------------------------*/
  16. /*                          RCS Information                           */
  17. /*--------------------------------------------------------------------*/
  18.  
  19. /*
  20.  *    $Id: dcpfpkt.c 1.12 1993/10/02 19:07:49 ahd Exp $
  21.  *
  22.  *    Revision history:
  23.  *    $Log: dcpfpkt.c $
  24.  * Revision 1.12  1993/10/02  19:07:49  ahd
  25.  * Suppress compiler warning
  26.  *
  27.  * Revision 1.11  1993/09/20  04:41:54  ahd
  28.  * OS/2 2.x support
  29.  *
  30.  * Revision 1.10  1993/07/31  16:27:49  ahd
  31.  * Changes in support of Robert Denny's Windows support
  32.  *
  33.  * Revision 1.9  1993/07/22  23:22:27  ahd
  34.  * First pass at changes for Robert Denny's Windows 3.1 support
  35.  *
  36.  * Revision 1.8  1993/05/30  00:01:47  ahd
  37.  * Multiple communications driver support
  38.  *
  39.  * Revision 1.7  1993/04/05  12:26:01  ahd
  40.  * Correct prototypes to match gpkt
  41.  *
  42.  * Revision 1.6  1993/04/05  04:35:40  ahd
  43.  * Allow unique send/receive packet sizes
  44.  *
  45.  * Revision 1.3  1992/11/19  02:36:29  ahd
  46.  * Revision 1.2  1992/11/15  20:10:47  ahd
  47.  * Clean up modem file support for different protocols
  48.  */
  49.  
  50. /*--------------------------------------------------------------------*/
  51. /*    Flow control ("f") protocol.                                    */
  52. /*                                                                    */
  53. /*    This protocol relies on flow control of the data stream.  It    */
  54. /*    is meant for working over links that can (almost) be            */
  55. /*    guaranteed to be errorfree, specifically X.25/PAD links.  A     */
  56. /*    sumcheck is carried out over a whole file only.  If a           */
  57. /*    transport fails the receiver can request retransmission(s).     */
  58. /*    This protocol uses a 7-bit datapath only, so it can be used     */
  59. /*    on links that are not 8-bit transparent.                        */
  60. /*                                                                    */
  61. /*    When using this protocol with an X.25 PAD:  Although this       */
  62. /*    protocol uses no control chars except CR, control chars NULL    */
  63. /*    and ^P are used before this protocol is started; since ^P is    */
  64. /*    the default char for accessing PAD X.28 command mode, be        */
  65. /*    sure to disable that access (PAD par 1).  Also make sure        */
  66. /*    both flow control pars (5 and 12) are set.  The CR used in      */
  67. /*    this proto is meant to trigger packet transmission, hence       */
  68. /*    par 3 should be set to 2; a good value for the Idle Timer       */
  69. /*    (par 4) is 10.  All other pars should be set to 0.              */
  70. /*                                                                    */
  71. /*    Normally a calling site will take care of setting the local     */
  72. /*    PAD pars via an X.28 command and those of the remote PAD via    */
  73. /*    an X.29 command, unless the remote site has a special           */
  74. /*    channel assigned for this protocol with the proper par          */
  75. /*    settings.                                                       */
  76. /*                                                                    */
  77. /*    Author:  Piet Beertema, CWI, Amsterdam, Sep 1984                */
  78. /*                                                                    */
  79. /*    Adapted to uupc 3.0 and THINK C 4.0 by Dave Platt, Jul 1991     */
  80. /*                                                                    */
  81. /*    Adapted to UUPC/extended by Drew Derbyshire, 1992               */
  82. /*--------------------------------------------------------------------*/
  83.  
  84. /*--------------------------------------------------------------------*/
  85. /*                        System include files                        */
  86. /*--------------------------------------------------------------------*/
  87.  
  88. #include <stdio.h>
  89. #include <time.h>
  90. #include <string.h>
  91.  
  92. /*--------------------------------------------------------------------*/
  93. /*                    UUPC/extended include files                     */
  94. /*--------------------------------------------------------------------*/
  95.  
  96. #include "lib.h"
  97. #include "dcp.h"
  98. #include "dcpfpkt.h"
  99. #include "dcpsys.h"
  100. #include "hostable.h"
  101. #include "security.h"
  102. #include "ssleep.h"
  103. #include "modem.h"
  104. #include "commlib.h"
  105.  
  106. /*--------------------------------------------------------------------*/
  107. /*                              Defines                               */
  108. /*--------------------------------------------------------------------*/
  109.  
  110. #ifndef MAXMSGLEN
  111. #define MAXMSGLEN BUFSIZ
  112. #endif /* MAXMSGLEN */
  113.  
  114. currentfile();
  115.  
  116. /*--------------------------------------------------------------------*/
  117. /*                    Internal function prototypes                    */
  118. /*--------------------------------------------------------------------*/
  119.  
  120. static short fsendresp(short state);
  121.  
  122. /*--------------------------------------------------------------------*/
  123. /*                          Global variables                          */
  124. /*--------------------------------------------------------------------*/
  125.  
  126. static short chksum;
  127.  
  128. /*--------------------------------------------------------------------*/
  129. /*    f o p e n p k                                                   */
  130. /*                                                                    */
  131. /*    Open "f" protocol to other system                               */
  132. /*--------------------------------------------------------------------*/
  133.  
  134. #ifdef __TURBOC__
  135. #pragma argsused
  136. #endif
  137.  
  138. short fopenpk(const boolean master)
  139. {
  140.    flowcontrol(TRUE);
  141.  
  142.    if ( M_fPacketSize > MAXPACK)
  143.       M_fPacketSize = MAXPACK;
  144.  
  145.    r_pktsize = s_pktsize = M_fPacketSize;
  146.    ssleep(2); /* Give peer time to perform corresponding port setup */
  147.    return DCP_OK;
  148. } /* fopenpk */
  149.  
  150. /*--------------------------------------------------------------------*/
  151. /*    f c l o s e p k                                                 */
  152. /*                                                                    */
  153. /*    Shutdown "f" procotol with other system                         */
  154. /*--------------------------------------------------------------------*/
  155.  
  156. short fclosepk()
  157. {
  158.    flowcontrol(FALSE);
  159.    return DCP_OK;
  160. } /* fclosepk */
  161.  
  162. /*--------------------------------------------------------------------*/
  163. /*    f w r m s g                                                     */
  164. /*                                                                    */
  165. /*    Send a control message to remote system with "f" procotol       */
  166. /*--------------------------------------------------------------------*/
  167.  
  168. short fwrmsg(char *str)
  169. {
  170.    char bufr[MAXMSGLEN];
  171.    char *s = bufr;
  172.  
  173.    while (*str)
  174.       *s++ = *str++;
  175.    if (*(s-1) == '\n')
  176.       s--;
  177.    *s++ = '\r';
  178.    if (swrite(bufr, (unsigned int) (s - bufr)) == (unsigned int)(s - bufr))
  179.       return DCP_OK;
  180.    else
  181.       return DCP_FAILED;
  182. } /* fwrmsg */
  183.  
  184. /*--------------------------------------------------------------------*/
  185. /*    f r d m s g                                                     */
  186. /*                                                                    */
  187. /*    Read a control message from remote host with "f" protocol       */
  188. /*--------------------------------------------------------------------*/
  189.  
  190. short frdmsg(char *str)
  191. {
  192.    char *smax;
  193.    char *s = str;
  194.  
  195.    smax = s + MAXPACK - 1;
  196.    for (;;) {
  197.       if (sread(s, 1, M_fPacketTimeout) <= 0)
  198.       {
  199.          printmsg(0,"frdmsg: timeout reading message");
  200.          *s++ = '\0';
  201.          goto msgerr;
  202.       }
  203.       if (*s == '\r')
  204.          break;
  205.       if (*s < ' ')
  206.          continue;
  207.       if (s++ >= smax)
  208.       {
  209.          printmsg(0,"frdmsg: buffer overflow");
  210.          *--s = '\0';
  211.          goto msgerr;
  212.       } /* if (s++ >= smax) */
  213.    }
  214.    *s = '\0';
  215.    return DCP_OK;
  216.  
  217. msgerr:
  218.    printmsg(0,"frdmsg: Message received \"%s\"", str);
  219.    return DCP_FAILED;
  220. } /* frdmsg */
  221.  
  222. /*--------------------------------------------------------------------*/
  223. /*    f g e t p k t                                                   */
  224. /*                                                                    */
  225. /*    Receive an "f" protocol packet of data from the other system    */
  226. /*--------------------------------------------------------------------*/
  227.  
  228. short fgetpkt(char *packet, short *bytes)
  229. {
  230.    char *op, c, *ip;
  231.    short sum, len, left;
  232.    char buf[5], tbuf[1];
  233.    short i;
  234.    static char special = 0;
  235.    static boolean eof = FALSE;
  236.  
  237. /*--------------------------------------------------------------------*/
  238. /*                    Handle EOF on previous call                     */
  239. /*--------------------------------------------------------------------*/
  240.  
  241.    if ( eof )
  242.    {
  243.       eof = FALSE;
  244.       printmsg(2,"fgetpkt: EOF from other host");
  245.       *bytes = 0;
  246.       if (fsendresp(DCP_OK) == DCP_OK)
  247.          return DCP_OK;
  248.       else
  249.          return DCP_FAILED;
  250.    } /* if ( eof ) */
  251.  
  252.    left = s_pktsize;
  253.    op = packet;
  254.    sum = chksum;
  255.  
  256. /*--------------------------------------------------------------------*/
  257. /*                     Loop to fill up one packet                     */
  258. /*--------------------------------------------------------------------*/
  259.  
  260.    do {
  261.       ip = tbuf;
  262.       len = sread(ip, 1, M_fPacketTimeout); /* single-byte reads for now */
  263.       if (len == 0) {
  264.          printmsg(0,"fgetpkt: Timeout after %d seconds", M_fPacketTimeout);
  265.          return DCP_FAILED;               /* Fail if timed out */
  266.       }
  267.       if ((*ip &= 0177) >= '\172') {
  268.          if (special) {
  269.             special = 0;
  270.             if (*ip++ != '\176')
  271.             {
  272.                printmsg(0,"fgetpkt: Did not expect character ^%c (x%02x)",
  273.                   (char) (*(ip-1) + 'A') , (short) *(ip-1));
  274.                goto dcorr;
  275.             }
  276.             len = 0;
  277.  
  278.             while (len < 5) {
  279.                i = sread(&buf[len], 5 - len, M_fPacketTimeout);
  280.                if (i == 0) {
  281.                   printmsg(0,
  282.                      "fgetpkt: Timeout reading %d chars after %d seconds",
  283.                               5 - len, M_fPacketTimeout);
  284.                   goto dcorr;
  285.                }
  286.                len += i;
  287.             }
  288.  
  289.             printmsg(6, "fgetpkt: buf=|%.*s|", len , packet);
  290.             if (buf[4] != '\r')
  291.             {
  292.                printmsg(0,
  293.                   "fgetpkt: error: Expected carriage return, "
  294.                    "not %s%c (x%02x)",
  295.                   (buf[4] < ' ') ? "^" : "" ,
  296.                   (char) (buf[4] + ((buf[4] < ' ') ? 'A' : 0)),
  297.                   (short) buf[4]);
  298.                goto dcorr;
  299.             }
  300.             sscanf(buf, "%4x", &chksum);
  301.             *bytes = op - packet;
  302.             if (chksum == sum) {
  303.                eof = TRUE;
  304.                printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
  305.                return DCP_OK;
  306.             } else {
  307.                printmsg(0, "fgetpkt: Checksum mismatch, told %04x, calc %04x",
  308.                             chksum, sum);
  309.                fsendresp(DCP_RETRY);
  310.                return DCP_RETRY;
  311.             }
  312.          }
  313.          special = *ip++;
  314.       } else {
  315.          if (*ip < '\040') {
  316.             printmsg(0,"fgetpkt: error: got control character ^%c (%x)",
  317.                   (char) (*ip + 'A') , (short) *ip);
  318.             goto dcorr;
  319.          }
  320.  
  321.          switch (special) {
  322.             case 0:
  323.                c = (char) (*ip++);
  324.                break;
  325.             case '\172':
  326.                c = (char) (*ip++ - 0100);
  327.                break;
  328.             case '\173':
  329.                c = (char) (*ip++ + 0100);
  330.                break;
  331.             case '\174':
  332.                c = (char) (*ip++ + 0100);
  333.                break;
  334.             case '\175':
  335.                c = (char) (*ip++ + 0200);
  336.                break;
  337.             case '\176':
  338.                c = (char) (*ip++ + 0300);
  339.                break;
  340.             default:
  341.                printmsg(0,"fgetpkt: Invalid special chracter 0x%2x",
  342.                           (short) special );
  343.                panic();
  344.                c = '\0';
  345.          }
  346.  
  347.          *op++ = c;
  348.          left --;
  349.          if (sum & 0x8000) {
  350.             sum <<= 1;
  351.             sum++;
  352.          } else
  353.             sum <<= 1;
  354.          sum += c & 0377;
  355.          sum &= 0xffff;
  356.          special = 0;
  357.       }
  358.    } while (left > 0);
  359.  
  360. /*--------------------------------------------------------------------*/
  361. /*            The packet is full of data, return to caller            */
  362. /*--------------------------------------------------------------------*/
  363.  
  364.    *bytes = s_pktsize;
  365.    printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
  366.    chksum = sum;
  367.    return DCP_OK;
  368.  
  369. /*--------------------------------------------------------------------*/
  370. /*            The data is corrupt; flush the incoming file            */
  371. /*--------------------------------------------------------------------*/
  372.  
  373. dcorr:
  374.    printmsg (0, "Data corrupted, skipping to EOF");
  375.  
  376.    len = 1;
  377.    while (len)
  378.       len = sread(packet, 1, M_fPacketTimeout);
  379.  
  380.    fsendresp(DCP_RETRY);
  381.    return DCP_RETRY;
  382. } /* fgetpkt */
  383.  
  384. /*--------------------------------------------------------------------*/
  385. /*    f s e n d p k t                                                 */
  386. /*                                                                    */
  387. /*    Send an "f" protocol packet to the other system                 */
  388. /*--------------------------------------------------------------------*/
  389.  
  390. short fsendpkt(char *ip, short len)
  391. {
  392.    char *op;
  393.    short sum, nl;
  394.    short ret;
  395.    char obuf[MAXPACK * 2];
  396.    op = obuf;
  397.    nl = 0;
  398.    sum = chksum;
  399.    if (len == 0)
  400.    {
  401.       printmsg(0,"fsendpkt: Internal error: zero length for packet");
  402.       return DCP_FAILED;
  403.    }
  404.    do {
  405.       if (sum & 0x8000) {
  406.          sum <<= 1;
  407.          sum++;
  408.       } else
  409.          sum <<= 1;
  410.       sum += *ip & 0377;
  411.       sum &= 0xffff;
  412.       if (*ip & 0200) {
  413.          *ip &= 0177;
  414.          if (*ip < 040) {
  415.             *op++ = '\174';
  416.             *op++ = (char) (*ip++ + 0100);
  417.          } else
  418.          if (*ip <= 0171) {
  419.             *op++ = '\175';
  420.             *op++ = *ip++;
  421.          }
  422.          else {
  423.             *op++ = '\176';
  424.             *op++ = (char) (*ip++ - 0100);
  425.          }
  426.          nl += 2;
  427.       } else {
  428.          if (*ip < 040) {
  429.             *op++ = '\172';
  430.             *op++ = (char) (*ip++ + 0100);
  431.             nl += 2;
  432.          } else
  433.          if (*ip <= 0171) {
  434.             *op++ = *ip++;
  435.             nl++;
  436.          } else {
  437.             *op++ = '\173';
  438.             *op++ = (char) (*ip++ - 0100);
  439.             nl += 2;
  440.          }
  441.       }
  442.    } while (--len > 0);
  443.    chksum = sum;
  444.    ret = swrite(obuf, nl);
  445.    if ( ret == nl )
  446.       return DCP_OK;
  447.    else
  448.       return DCP_FAILED;
  449. } /* fsendpkt */
  450.  
  451. /*--------------------------------------------------------------------*/
  452. /*    f f i l e p k t                                                 */
  453. /*                                                                    */
  454. /*    Prepare for processing an "f" procotol file transfer            */
  455. /*--------------------------------------------------------------------*/
  456.  
  457. short ffilepkt( void)
  458. {
  459.    chksum = 0xffff;
  460.    printmsg(3,"ffilepkt: Checksum reset");
  461.    return DCP_OK;
  462. } /* ffilepkt */
  463.  
  464. /*--------------------------------------------------------------------*/
  465. /*    f e o f                                                         */
  466. /*                                                                    */
  467. /*    Transmit "f" protocol end of file to the other system           */
  468. /*--------------------------------------------------------------------*/
  469.  
  470. short feofpkt( void )
  471. {
  472.    char ibuf[MAXMSGLEN];
  473.  
  474. /*--------------------------------------------------------------------*/
  475. /*               Transmit EOF with an attached checksum               */
  476. /*--------------------------------------------------------------------*/
  477.  
  478.    printmsg(2,"feofpkt: sending EOF");
  479.    sprintf(ibuf, "\176\176%04x", chksum);
  480.    printmsg(2,"--> %s", ibuf);
  481.    fwrmsg(ibuf);
  482.  
  483. /*--------------------------------------------------------------------*/
  484. /*                 Now get the response and report it                 */
  485. /*--------------------------------------------------------------------*/
  486.  
  487.    if (frdmsg(ibuf) == DCP_FAILED)
  488.       return DCP_FAILED;
  489.  
  490.    printmsg(2,"<-- %s",ibuf);
  491.  
  492. /*--------------------------------------------------------------------*/
  493. /*              Determine our next step from the result               */
  494. /*--------------------------------------------------------------------*/
  495.  
  496.    switch(*ibuf)
  497.    {
  498.       case 'R':
  499.          return DCP_RETRY;
  500.  
  501.       case 'G':
  502.          return DCP_OK;
  503.  
  504.       default:
  505.          return DCP_FAILED;
  506.  
  507.    } /* switch */
  508.  
  509. } /* feofpkt */
  510.  
  511. /*--------------------------------------------------------------------*/
  512. /*    f s e n d r e s p                                               */
  513. /*                                                                    */
  514. /*    Send result to a file transfer to other host                    */
  515. /*--------------------------------------------------------------------*/
  516.  
  517. static short fsendresp(short state)
  518. {
  519.    char *s;
  520.    switch (state)
  521.    {
  522.       case DCP_OK:
  523.          s = "G";
  524.          break;
  525.  
  526.       case DCP_RETRY:
  527.          s = "R";
  528.          break;
  529.  
  530.       default:
  531.          s = "Q";
  532.          break;
  533.    }
  534.  
  535.    printmsg(2,"--> %s", s);
  536.    return fwrmsg(s);
  537.  
  538. } /* fsendresp */
  539.